Show code
options(tigris_use_cache = TRUE)
library(tidyverse)
library(tidycensus)
library(tigris)
library(sf)
library(leaflet)
library(knitr)
library(here)The purpose of this analysis is the identify the counties in the United States that have the highest concentration of military personnel residential locations, and to identify the distribution of military personnel within those counties.
I draw on the following datasets:
The American Community Survey
The Decennial Census of Island Areas
This analysis uses the following R packages:
options(tigris_use_cache = TRUE)
library(tidyverse)
library(tidycensus)
library(tigris)
library(sf)
library(leaflet)
library(knitr)
library(here)Table B23025 in the American Community Survey includes data on the number of people over the age of 15 in each of the following employment categories:
Total population over 15 (B23025_001)
Total population in the labor force (B23025_002)
Total population in the civilian labor force (B23025_003)
Total employed population in the civilian labor force (B23025_004)
Total unemployed population in the civilian labor force (B23025_005)
Total population serving in the armed forces (B23025_006)
Total population over 15 that is not in the labor force (B23025_007)
I will load the number of armed forces personnel and the number of people in the civilian labor force for each county in the United States, and calculate the percentage of the total U.S.-based active-duty military force living in each county.
The American Community Survey (2019-2023) indicates that there are are total of 1,291,134 military personnel stationed in the United States. DoD data for June 2021 indicates that there were 1,206,986 military personnel assigned to the United States at that time and 172,881 stationed overseas (including 10 in the U.S. Virgin Islands, 20 in the Northern Mariana Islands, and 6,161 on Guam). To get a rough estimate of the total share of the the total military living in each of these counties, I will assume 200,000 troops overseas (to err on the side of underestimating the share of the total military in any county (this method would suggest that about 0.4 percent of military members were stationed in Guam during that period).
variable_set <- c(civil_ = "B23025_003",
milit_ = "B23025_006")
county_workers <- get_acs(geography = "county",
variables = variable_set,
year = 2023,
output = "wide",
geometry = TRUE,
progress_bar = FALSE) |>
filter(milit_E > 0) |>
st_transform("WGS84") |>
mutate(pct_of_military = milit_E / (sum(milit_E)+200000)) I can also get very a rough indication of which military branches are located in each county, based on the names of military installations that the census uses as landmarks.
installations <- military() |>
mutate(branch = case_when(str_detect(FULLNAME, "Army") ~ "Army",
str_detect(FULLNAME, "Ft ") ~ "Army",
str_detect(FULLNAME, "AFB") ~ "Air Force",
str_detect(FULLNAME, "Naval") ~ "Navy",
str_detect(FULLNAME, "Navy") ~ "Navy",
str_detect(FULLNAME, "Marine Corps") ~ "Marines",
str_detect(FULLNAME, "Coast Guard") ~ "Coast Guard",
str_detect(FULLNAME, "Joint") ~ "Joint",
str_detect(FULLNAME, "Fld") ~ "Air Force",
str_detect(FULLNAME, "Air Force") ~ "Air Force",
str_detect(FULLNAME, " Air ") ~ "Air Force",
str_detect(FULLNAME, "Arprt") ~ "Air Force",
str_detect(FULLNAME, "Nas") ~ "Navy",
str_detect(FULLNAME, "Mil Res") ~ "Army",
str_detect(FULLNAME, "Ng") ~ "Army",
str_detect(FULLNAME, "Ang") ~ "Air Force",
str_detect(FULLNAME, "Cp") ~ "Army",
str_detect(FULLNAME, "Airfield") ~ "Air Force",
str_detect(FULLNAME, "Air National Guard") ~
"Air Force",
str_detect(FULLNAME, "National Guard") ~ "Army",
str_detect(FULLNAME, "Af") ~ "Air Force",
str_detect(FULLNAME, "Nb") ~ "Navy",
TRUE ~ "Unknown")) |>
st_transform("WGS84")
unclassified <- installations |>
filter(branch == "Unknown")
maybe_army <- installations |>
filter(branch == "Army") |>
st_join(county_workers) |>
st_drop_geometry() |>
group_by(NAME) |>
summarize(maybe_army = n() > 0)
maybe_AF <- installations |>
filter(branch == "Air Force") |>
st_join(county_workers) |>
st_drop_geometry() |>
group_by(NAME) |>
summarize(maybe_AF = n() > 0)
maybe_marines <- installations |>
filter(branch == "Marines") |>
st_join(county_workers) |>
st_drop_geometry() |>
group_by(NAME) |>
summarize(maybe_marines = n() > 0)
maybe_joint <- installations |>
filter(branch == "Joint") |>
st_join(county_workers) |>
st_drop_geometry() |>
group_by(NAME) |>
summarize(maybe_joint = n() > 0)
maybe_navy <- installations |>
filter(branch == "Navy") |>
st_join(county_workers) |>
st_drop_geometry() |>
group_by(NAME) |>
summarize(maybe_navy = n() > 0)
maybe_coast_guard <- installations |>
filter(branch == "Coast Guard") |>
st_join(county_workers) |>
st_drop_geometry() |>
group_by(NAME) |>
summarize(maybe_CG = n() > 0)
county_workers <- county_workers |>
left_join(maybe_AF) |>
left_join(maybe_army) |>
left_join(maybe_coast_guard) |>
left_join(maybe_joint) |>
left_join(maybe_marines) |>
left_join(maybe_navy) |>
replace_na(list(maybe_navy = FALSE,
maybe_AF = FALSE,
maybe_coast_guard = FALSE,
maybe_joint = FALSE,
maybe_marines = FALSE,
maybe_army = FALSE,
maybe_CG = FALSE)) |>
mutate(`Branch (guess)` = case_when(maybe_navy +
maybe_marines +
maybe_army +
maybe_joint +
maybe_CG +
maybe_AF > 1 ~ "Multiple",
maybe_joint ~ "Multiple",
maybe_navy ~ "Navy",
maybe_marines ~ "Marines",
maybe_army ~ "Army",
maybe_CG ~ "Coast Guard",
maybe_AF ~ "Air Force",
TRUE ~ "Unknown"))Here are the twenty counties where residents represent the highest shares of all U.S. military personnel.
top_pct_of_military <- county_workers |>
st_drop_geometry() |>
mutate(`Percent of total military` =
paste0(round(100*pct_of_military), "%")) |>
arrange(-pct_of_military) |>
head(n=20)
top_pct_of_military|>
select(NAME, `Percent of total military`, `Branch (guess)`) |>
kable()| NAME | Percent of total military | Branch (guess) |
|---|---|---|
| San Diego County, California | 6% | Multiple |
| Honolulu County, Hawaii | 3% | Multiple |
| Onslow County, North Carolina | 3% | Marines |
| El Paso County, Colorado | 2% | Multiple |
| Cumberland County, North Carolina | 2% | Multiple |
| Bexar County, Texas | 2% | Multiple |
| Norfolk city, Virginia | 2% | Navy |
| Pierce County, Washington | 2% | Multiple |
| Virginia Beach city, Virginia | 1% | Multiple |
| Bell County, Texas | 1% | Army |
| El Paso County, Texas | 1% | Army |
| Duval County, Florida | 1% | Multiple |
| San Bernardino County, California | 1% | Multiple |
| Kitsap County, Washington | 1% | Multiple |
| Okaloosa County, Florida | 1% | Air Force |
| Montgomery County, Tennessee | 1% | Army |
| Fairfax County, Virginia | 1% | Army |
| Anne Arundel County, Maryland | 1% | Multiple |
| Lake County, Illinois | 1% | Navy |
| Jefferson County, New York | 1% | Army |
Approximately one third of the total U.S. military force lives in these 20 counties. Approximately one quarter lives in the top ten counties listed above.
Some of the counties are in fairly close proximity to one another and are considered to be part of the same region for the analysis below.
The rest of this analysis will focus on the ten regions with the greatest numbers of military personnel, together with the counties immediately adjacent to them.
Here’s a function to grab tract- or block-group-level data from the county of interest and all adjacent counties.
map_detail_mil <- function(counties,
county_name,
level) {
variable_set <- c(civil_ = "B23025_003",
milit_ = "B23025_006")
buffer <- counties |>
filter(NAME %in% county_name) |>
st_buffer(dist = 3000)
region <- counties |>
st_filter(buffer) |>
mutate(state_code = substr(GEOID, 1, 2))
states <- unique(region$state_code)
region_state_1 <- region |>
filter(state_code == states[1])
subarea <- get_acs(geography = level,
state = states[1],
county = substr(region_state_1$GEOID, 3, 5),
variables = variable_set,
year = 2023,
output = "wide",
geometry = TRUE,
progress_bar = FALSE) |>
filter(milit_E > 0) |>
st_transform("WGS84")
if(length(states) > 1) {
for (i in 2:length(states)) {
region_state_next <- region |>
filter(state_code == states[i])
subarea_next <- get_acs(geography = level,
state = states[i],
county = substr(region_state_next$GEOID, 3, 5),
variables = variable_set,
year = 2023,
output = "wide",
geometry = TRUE,
progress_bar = FALSE) |>
filter(milit_E > 0) |>
st_transform("WGS84")
subarea <- rbind(subarea, subarea_next)
}
}
subarea_palette <- colorNumeric("viridis",
domain = log10(subarea$milit_E),
reverse = TRUE)
subarea_labels <- paste0(subarea$milit_E,
" military personnel<br/>",
subarea$civil_E,
" civilian workers") |>
lapply(htmltools::HTML)
map <- leaflet(subarea) |>
addProviderTiles(provider = "CartoDB.Positron") |>
addPolygons(weight = 1,
color = NA,
fillColor = ~subarea_palette(log10(milit_E)),
fillOpacity = 0.7,
highlightOptions = highlightOptions(weight = 3,
fillOpacity = 0.5),
label = subarea_labels) |>
addLegend(pal = subarea_palette,
values = ~log10(milit_E),
labFormat = labelFormat(prefix = "10^"),
opacity = 0.7,
title = "Number of\narmed forces\npersonnel",
position = "bottomleft")
data <- region |>
st_drop_geometry() |>
rename(`Estimated number of military personnel` = milit_E,
County = NAME) |>
mutate(`Estimated percent of total military force` =
100*pct_of_military) |>
select(County,
`Estimated number of military personnel`,
`Estimated percent of total military force`) |>
arrange(-`Estimated number of military personnel`)
data_sums <- tibble(County = "Total",
`Estimated number of military personnel` =
sum(data$`Estimated number of military personnel`),
`Estimated percent of total military force` =
sum(data$`Estimated percent of total military force`))
data = rbind(data, data_sums)
list(map = map, data = data)
}Here is a table showing the number of military members in San Diego and San Bernardino Counties and the adjacent counties.
There are many military installations in this area, including:
Amphibious Base Coronado East
Chocolate Mountains Aerial Gunnery Range
Holtville Carrier Landing Site
Los Alamitos Reserve Center and Air Station
March Air Force Base
Camp Pendleton
Marine Corps Air Station Miramar
Naval Base Point Loma
Naval Base San Diego
Yuma Proving Ground
san_diego <- map_detail_mil(county_workers,
c("San Diego County, California",
"San Bernardino County, California"),
level = "tract")
kable(san_diego$data, digits = 1)| County | Estimated number of military personnel | Estimated percent of total military force |
|---|---|---|
| San Diego County, California | 88041 | 5.9 |
| San Bernardino County, California | 14659 | 1.0 |
| Clark County, Nevada | 10543 | 0.7 |
| Riverside County, California | 6057 | 0.4 |
| Los Angeles County, California | 5659 | 0.4 |
| Orange County, California | 2889 | 0.2 |
| Kern County, California | 2439 | 0.2 |
| Imperial County, California | 377 | 0.0 |
| Mohave County, Arizona | 137 | 0.0 |
| La Paz County, Arizona | 23 | 0.0 |
| Total | 130824 | 8.8 |
And here is an interactive map of the number of military personnel in each tract across those counties.
san_diego$mapThe following military installations are located in Honolulu County:
Marine Corps Base Hawaii
Fort Shafter (Army)
Joint Base Pearl Harbor-Hickam (Navy/Air Force)
Integrated Support Command Honolulu (Coast Guard)
Schofield Barracks (Army)
honolulu <- map_detail_mil(county_workers,
"Honolulu County, Hawaii",
level = "tract")
kable(honolulu$data, digits = 1)| County | Estimated number of military personnel | Estimated percent of total military force |
|---|---|---|
| Honolulu County, Hawaii | 48139 | 3.2 |
| Total | 48139 | 3.2 |
And here is an interactive map of the number of military personnel in each tract on the island.
honolulu$mapOnslow and Cumberland County represent adjacent regions in North Carolina.
Marine Corps Base Camp Lejeune and Marine Corps Air Station New River are both in Onslow County. Fort Bragg (which was renamed Fort Liberty in 2023 and renamed back to Fort Bragg in 2025) is located in Cumberland County.
onslow <- map_detail_mil(county_workers,
c("Onslow County, North Carolina",
"Cumberland County, North Carolina"),
level = "tract")
kable(onslow$data, digits = 1)| County | Estimated number of military personnel | Estimated percent of total military force |
|---|---|---|
| Onslow County, North Carolina | 40194 | 2.7 |
| Cumberland County, North Carolina | 33537 | 2.2 |
| Harnett County, North Carolina | 4686 | 0.3 |
| Moore County, North Carolina | 3965 | 0.3 |
| Hoke County, North Carolina | 2724 | 0.2 |
| Carteret County, North Carolina | 677 | 0.0 |
| Pender County, North Carolina | 484 | 0.0 |
| Sampson County, North Carolina | 185 | 0.0 |
| Robeson County, North Carolina | 128 | 0.0 |
| Duplin County, North Carolina | 56 | 0.0 |
| Bladen County, North Carolina | 31 | 0.0 |
| Jones County, North Carolina | 8 | 0.0 |
| Total | 86675 | 5.8 |
onslow$mapThe United States Air Force Academy is located in El Paso County, Colorado, as is Fort Carson, which is an Army post.
el_paso <- map_detail_mil(county_workers,
"El Paso County, Colorado",
level = "tract")
kable(el_paso$data, digits = 1)| County | Estimated number of military personnel | Estimated percent of total military force |
|---|---|---|
| El Paso County, Colorado | 34817 | 2.3 |
| Douglas County, Colorado | 934 | 0.1 |
| Pueblo County, Colorado | 550 | 0.0 |
| Fremont County, Colorado | 75 | 0.0 |
| Teller County, Colorado | 68 | 0.0 |
| Elbert County, Colorado | 44 | 0.0 |
| Lincoln County, Colorado | 13 | 0.0 |
| Total | 36501 | 2.4 |
el_paso$mapThe following military installations are in Bexar County, Texas:
Camp Bullis (Army)
Joint Base San Antonio, which includes
Randolph Air Force Base
Lackland Air Force Base
Fort Sam Houston (Army)
bexar <- map_detail_mil(county_workers,
"Bexar County, Texas",
level = "tract")
kable(bexar$data, digits = 1)| County | Estimated number of military personnel | Estimated percent of total military force |
|---|---|---|
| Bexar County, Texas | 26549 | 1.8 |
| Guadalupe County, Texas | 1720 | 0.1 |
| Comal County, Texas | 539 | 0.0 |
| Wilson County, Texas | 193 | 0.0 |
| Medina County, Texas | 115 | 0.0 |
| Kendall County, Texas | 34 | 0.0 |
| Atascosa County, Texas | 8 | 0.0 |
| Total | 29158 | 2.0 |
Naval Station Norfolk, in Norfolk, Virginia is the largest Naval installation in the world. The adjacent city of Virginia Beach is also home to several military bases including:
Naval Air Station Oceana
Training Support Center Hampton Roads
Joint Expeditionary Base East
norfolk <- map_detail_mil(county_workers,
c("Norfolk city, Virginia",
"Virginia Beach city, Virginia"),
level = "tract")
kable(norfolk$data, digits = 1)| County | Estimated number of military personnel | Estimated percent of total military force |
|---|---|---|
| Norfolk city, Virginia | 24788 | 1.7 |
| Virginia Beach city, Virginia | 22194 | 1.5 |
| Chesapeake city, Virginia | 8262 | 0.6 |
| Hampton city, Virginia | 6177 | 0.4 |
| Portsmouth city, Virginia | 3876 | 0.3 |
| Currituck County, North Carolina | 537 | 0.0 |
| Total | 65834 | 4.4 |
norfolk$mapPierce County is home to Joint Base Lewis-McChord, a joint base serving the Army and the Air Force.
The neighboring Kitsap County also includes the following naval installations:
Naval Station Bremerton
Submarine Base Bangor
Keyport
Manchester Fuel Depot
Jackson Park Housing
pierce <- map_detail_mil(county_workers,
c("Pierce County, Washington",
"Kitsap County, Washington"),
level = "tract")
kable(pierce$data, digits = 1)| County | Estimated number of military personnel | Estimated percent of total military force |
|---|---|---|
| Pierce County, Washington | 23418 | 1.6 |
| Kitsap County, Washington | 13508 | 0.9 |
| Thurston County, Washington | 6103 | 0.4 |
| King County, Washington | 2361 | 0.2 |
| Yakima County, Washington | 169 | 0.0 |
| Mason County, Washington | 151 | 0.0 |
| Jefferson County, Washington | 120 | 0.0 |
| Lewis County, Washington | 89 | 0.0 |
| Kittitas County, Washington | 88 | 0.0 |
| Total | 46007 | 3.1 |
pierce$mapFort Cavazos (formerly Fort Hood) is a very large army base that straddles Bell County and Coryell County in Texas.
bell <- map_detail_mil(county_workers,
"Bell County, Texas",
level = "tract")
kable(bell$data, digits = 1)| County | Estimated number of military personnel | Estimated percent of total military force |
|---|---|---|
| Bell County, Texas | 20833 | 1.4 |
| Coryell County, Texas | 10451 | 0.7 |
| Williamson County, Texas | 1348 | 0.1 |
| McLennan County, Texas | 136 | 0.0 |
| Lampasas County, Texas | 106 | 0.0 |
| Milam County, Texas | 8 | 0.0 |
| Total | 32882 | 2.2 |
bell$mapFort Bliss is located in El Paso County, Texas, and Holloman Air Force Base is located in the neighboring Otero County, New Mexico.
el_paso_tx <- map_detail_mil(county_workers,
"El Paso County, Texas",
level = "tract")
kable(el_paso_tx$data, digits = 1)| County | Estimated number of military personnel | Estimated percent of total military force |
|---|---|---|
| El Paso County, Texas | 18859 | 1.3 |
| Otero County, New Mexico | 4271 | 0.3 |
| Doña Ana County, New Mexico | 1163 | 0.1 |
| Total | 24293 | 1.6 |
el_paso_tx$mapThere are several miliary installations in the Washington, DC area, including the Pentagon and the United States Naval Academy.
dc_area <- map_detail_mil(county_workers,
c("Fairfax County, Virginia",
"Anne Arundel County, Maryland"),
level = "tract")
kable(dc_area$data, digits = 1)| County | Estimated number of military personnel | Estimated percent of total military force |
|---|---|---|
| Fairfax County, Virginia | 12404 | 0.8 |
| Anne Arundel County, Maryland | 11517 | 0.8 |
| Prince William County, Virginia | 6441 | 0.4 |
| Prince George’s County, Maryland | 4052 | 0.3 |
| Montgomery County, Maryland | 3548 | 0.2 |
| District of Columbia, District of Columbia | 3463 | 0.2 |
| Arlington County, Virginia | 3455 | 0.2 |
| Alexandria city, Virginia | 3364 | 0.2 |
| Howard County, Maryland | 2461 | 0.2 |
| Charles County, Maryland | 1842 | 0.1 |
| Loudoun County, Virginia | 1335 | 0.1 |
| Calvert County, Maryland | 1161 | 0.1 |
| Baltimore County, Maryland | 867 | 0.1 |
| Baltimore city, Maryland | 759 | 0.1 |
| Falls Church city, Virginia | 115 | 0.0 |
| Fairfax city, Virginia | 68 | 0.0 |
| Manassas city, Virginia | 34 | 0.0 |
| Total | 56886 | 3.8 |
dc_area$mapIn case Census tracts are not specific enough, we can also see the distribution of military personnel within regions at the census block group level. Note that estimate uncertainty is greater for lower-level geographies. In other words, reported estimates for the number of military personnel in a county are generally going to be more accurate than those for the number in a census tract, and estimates for census tracts will be more accurate than those for census block groups.
san_diego_bgs <- map_detail_mil(county_workers,
c("San Diego County, California",
"San Bernardino County, California"),
level = "block group")
san_diego_bgs$maphonolulu_bgs <- map_detail_mil(county_workers,
"Honolulu County, Hawaii",
level = "block group")
honolulu_bgs$maponslow_bgs <- map_detail_mil(county_workers,
c("Onslow County, North Carolina",
"Cumberland County, North Carolina"),
level = "block group")
onslow_bgs$mapel_paso_co_bgs <- map_detail_mil(county_workers,
"El Paso County, Colorado",
level = "block group")
el_paso_co_bgs$mapbexar_bgs <- map_detail_mil(county_workers,
"Bexar County, Texas",
level = "block group")
bexar_bgs$mapnorfolk_bgs <- map_detail_mil(county_workers,
c("Norfolk city, Virginia",
"Virginia Beach city, Virginia"),
level = "block group")
norfolk_bgs$mappierce_bgs <- map_detail_mil(county_workers,
c("Pierce County, Washington",
"Kitsap County, Washington"),
level = "block group")
pierce_bgs$mapbell_bg <- map_detail_mil(county_workers,
"Bell County, Texas",
level = "block group")
bell_bg$mapel_paso_tx_bgs <- map_detail_mil(county_workers,
"El Paso County, Texas",
level = "block group")
el_paso_tx_bgs$mapdc_area_bg <- map_detail_mil(county_workers,
c("Fairfax County, Virginia",
"Anne Arundel County, Maryland"),
level = "block group")
dc_area_bg$mapThese are the total estimated military personnel across the ten regions described above.
all_regions <- list(`San Diego and San Bernardino` = san_diego$data,
Honolulu = honolulu$data,
`Onslow and Cumberland` = onslow$data,
`Colorado Springs` = el_paso$data,
`Bexar, Texas` = bexar$data,
`Norfolk and Virginia Beach` = norfolk$data,
`Pierce and Kitsap` = pierce$data,
`Bell, Texas` = bell$data,
`El Paso, Texas` = el_paso_tx$data,
`DC Area` = dc_area$data)
region_totals <- tibble(Region = "none",
`Estimated number of military personnel` = 0,
`Estimated percent of total military force` = 0) |>
filter(Region != "none")
for (i in 1:length(all_regions)) {
next_region <- all_regions[[i]] |>
filter(County == "Total") |>
mutate(Region = names(all_regions)[i]) |>
select(Region,
`Estimated number of military personnel`,
`Estimated percent of total military force`)
region_totals <- rbind(region_totals, next_region)
}
region_sums = tibble(Region = "Total",
`Estimated number of military personnel` =
sum(region_totals$`Estimated number of military personnel`),
`Estimated percent of total military force` =
sum(region_totals$`Estimated percent of total military force`))
region_totals <- arrange(region_totals, -`Estimated number of military personnel`) |>
rbind(region_sums)
region_totals |>
kable(digits = 1, format.args = list(big.mark = ","))| Region | Estimated number of military personnel | Estimated percent of total military force |
|---|---|---|
| San Diego and San Bernardino | 130,824 | 8.8 |
| Onslow and Cumberland | 86,675 | 5.8 |
| Norfolk and Virginia Beach | 65,834 | 4.4 |
| DC Area | 56,886 | 3.8 |
| Honolulu | 48,139 | 3.2 |
| Pierce and Kitsap | 46,007 | 3.1 |
| Colorado Springs | 36,501 | 2.4 |
| Bell, Texas | 32,882 | 2.2 |
| Bexar, Texas | 29,158 | 2.0 |
| El Paso, Texas | 24,293 | 1.6 |
| Total | 557,199 | 37.4 |